#import <ctype.h>

#import <UIKit/UIKit.h>
#import <UIKit/UIFont.h>
#import <UIKit/UIColor.h>

#import "KeyboardPanel.h"
#import "TextView.h"
#import "PadPanel.h"
#import "QtKey.h"

typedef enum
{
	UIBarStyleDefault          = 0,
	UIBarStyleBlackOpaque      = 1,
	UIBarStyleBlackTranslucent = 2,
} UIBarStyle;

typedef enum
{
	UIButtonTypeCustom = 0,
	UIButtonTypeRoundedRect,
	UIButtonTypeDetailDisclosure,
	UIButtonTypeInfoLight,
	UIButtonTypeInfoDark,
	UIButtonTypeContactAdd,
} UIButtonType;

enum
{
	UIControlEventTouchDown           = 1 <<  0,
	UIControlEventTouchDownRepeat     = 1 <<  1,
	UIControlEventTouchDragInside     = 1 <<  2,
	UIControlEventTouchDragOutside    = 1 <<  3,
	UIControlEventTouchDragEnter      = 1 <<  4,
	UIControlEventTouchDragExit       = 1 <<  5,
	UIControlEventTouchUpInside       = 1 <<  6,
	UIControlEventTouchUpOutside      = 1 <<  7,
	UIControlEventTouchCancel         = 1 <<  8,
	
	UIControlEventValueChanged        = 1 << 12,
	
	UIControlEventEditingDidBegin     = 1 << 16,
	UIControlEventEditingChanged      = 1 << 17,
	UIControlEventEditingDidEnd       = 1 << 18,
	UIControlEventEditingDidEndOnExit = 1 << 19,
	
	UIControlEventAllTouchEvents      = 0x00000FFF,
	UIControlEventAllEditingEvents    = 0x000F0000,
	UIControlEventApplicationReserved = 0x0F000000,
	UIControlEventSystemReserved      = 0xF0000000,
	UIControlEventAllEvents           = 0xFFFFFFFF
};

enum
{
	UIControlStateNormal               = 0,
	UIControlStateHighlighted          = 1 << 0,
	UIControlStateDisabled             = 1 << 1,
	UIControlStateSelected             = 1 << 2,
	UIControlStateApplicationReserved  = 0x00FF0000,
	UIControlStateReserved             = 0xFF000000
};

@class UIButton;

@implementation KeyboardPanel

@synthesize textView;

- (UIButton *)buttonWithFrame:(CGRect)frame title:(NSString *)title keyArray:(NSArray *)keys
{
	UIButton *b = [UIButton buttonWithType:UIButtonTypeCustom];
	[b setFrame:frame];
	[b setShowsTouchWhenHighlighted:YES];
	// [b setFont:[UIFont systemFontOfSize:36.0]];
	// [b setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
	[b setBackgroundImage:[UIImage imageNamed:@"Key.png"] forState:UIControlStateNormal];
	[b setTitle:title forState:UIControlStateNormal];
	[b addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchDown];
	[b addTarget:self action:@selector(buttonReleased:) forControlEvents:UIControlEventTouchUpInside];
	[b addTarget:self action:@selector(buttonReleased:) forControlEvents:UIControlEventTouchUpOutside];
	
	if (keys)	[keySets setObject:keys forKey:[NSNumber numberWithInteger:b]];
	
	return b;
}

- (id)initWithFrame:(CGRect)frame
{
	if ((self = [super initWithFrame:frame]) == nil)	return nil;
	
	keySets = [[NSMutableDictionary alloc] initWithCapacity:8];
	
	shiftDown = ctrlDown = altDown = winDown = NO;
	
	NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
	
	// UITextView
	CGRect textViewFrame = CGRectMake(0, 0, frame.size.width - 40, frame.size.height - 160 - [UIKeyboard defaultSize].height + 49);
	self.textView = [[[TextView alloc] initWithFrame:textViewFrame] autorelease];
	[textView setTextColor:[UIColor whiteColor]];
	[textView setBackgroundColor:[UIColor blackColor]];
	[textView setFont:[UIFont systemFontOfSize:[defaults floatForKey:@"text_font_size"]]];
	[self addSubview:self.textView];
	
	UIView *keyControlView = [[UIView alloc] initWithFrame:CGRectMake(frame.size.width - 40, 0, 40, textViewFrame.size.height)];
	[keyControlView addSubview:[self buttonWithFrame:CGRectMake( 0,  0, 40, 40) title:@"Hide" keyArray:nil]];
	[keyControlView addSubview:[self buttonWithFrame:CGRectMake( 0, 40, 40, 40) title:@"Fn" keyArray:nil]];
	[self addSubview:keyControlView];
	
	// UITransitionView to switch function keys and normal keys
	CGRect keysFrame = CGRectMake(0, frame.size.height - [UIKeyboard defaultSize].height - 160 + 49, frame.size.width, 160);
	keysView = [[UITransitionView alloc] initWithFrame:keysFrame];
	[self addSubview:keysView];
	
	// Keys
	normalKeys = [[UIView alloc] initWithFrame:CGRectMake(0, 0, keysFrame.size.width, keysFrame.size.height)];
	[normalKeys addSubview:[self buttonWithFrame:CGRectMake(  0,   0, 60, 40) title:@"ESC" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_Escape]]]];
	[normalKeys addSubview:[self buttonWithFrame:CGRectMake( 60,   0, 40, 40) title:@"`/~" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_Zenkaku_Hankaku]]]];
	[normalKeys addSubview:[self buttonWithFrame:CGRectMake(140,   0, 60, 40) title:@"Ins" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_Insert]]]];
	[normalKeys addSubview:[self buttonWithFrame:CGRectMake(200,   0, 60, 40) title:@"Home" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_Home]]]];
	[normalKeys addSubview:[self buttonWithFrame:CGRectMake(260,   0, 60, 40) title:@"PgUp" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_PageUp]]]];
	
	[normalKeys addSubview:[self buttonWithFrame:CGRectMake(  0,  40, 60, 40) title:@"Tab" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_Tab]]]];
	[normalKeys addSubview:[self buttonWithFrame:CGRectMake( 60,  40, 60, 40) title:@"Scrl" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_ScrollLock]]]];
	[normalKeys addSubview:[self buttonWithFrame:CGRectMake(140,  40, 60, 40) title:@"Del" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_Delete]]]];
	[normalKeys addSubview:[self buttonWithFrame:CGRectMake(200,  40, 60, 40) title:@"End" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_End]]]];
	[normalKeys addSubview:[self buttonWithFrame:CGRectMake(260,  40, 60, 40) title:@"PgDn" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_PageDown]]]];
	
	[normalKeys addSubview:shift = [self buttonWithFrame:CGRectMake(  0,  80, 60, 40) title:@"Shift" keyArray:nil]];
	[normalKeys addSubview:[self buttonWithFrame:CGRectMake( 60,  80, 60, 40) title:@"Caps" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_CapsLock]]]];
	[normalKeys addSubview:[self buttonWithFrame:CGRectMake(120,  80, 40, 40) title:@"App" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_Menu]]]];
	[normalKeys addSubview:[self buttonWithFrame:CGRectMake(240,  80, 40, 40) title:@"↑" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_Up]]]];
	
	[normalKeys addSubview:ctrl = [self buttonWithFrame:CGRectMake(  0, 120, 60, 40) title:@"Ctrl" keyArray:nil]];
	[normalKeys addSubview:alt = [self buttonWithFrame:CGRectMake( 60, 120, 60, 40) title:@"Alt" keyArray:nil]];
	[normalKeys addSubview:win = [self buttonWithFrame:CGRectMake(120, 120, 40, 40) title:@"Win" keyArray:nil]];
	[normalKeys addSubview:[self buttonWithFrame:CGRectMake(200, 120, 40, 40) title:@"←" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_Left]]]];
	[normalKeys addSubview:[self buttonWithFrame:CGRectMake(240, 120, 40, 40) title:@"↓" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_Down]]]];
	[normalKeys addSubview:[self buttonWithFrame:CGRectMake(280, 120, 40, 40) title:@"→" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_Right]]]];
	
	functionKeys = [[UIView alloc] initWithFrame:CGRectMake(0, 0, keysFrame.size.width, keysFrame.size.height)];
	[functionKeys addSubview:[self buttonWithFrame:CGRectMake(  0,   0, 40, 40) title:@"F1" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_F1]]]];
	[functionKeys addSubview:[self buttonWithFrame:CGRectMake( 40,   0, 40, 40) title:@"F2" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_F2]]]];
	[functionKeys addSubview:[self buttonWithFrame:CGRectMake( 80,   0, 40, 40) title:@"F3" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_F3]]]];
	[functionKeys addSubview:[self buttonWithFrame:CGRectMake(120,   0, 40, 40) title:@"F4" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_F4]]]];
	[functionKeys addSubview:[self buttonWithFrame:CGRectMake(160,   0, 40, 40) title:@"F5" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_F5]]]];
	[functionKeys addSubview:[self buttonWithFrame:CGRectMake(200,   0, 40, 40) title:@"F6" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_F6]]]];
	[functionKeys addSubview:[self buttonWithFrame:CGRectMake(240,   0, 40, 40) title:@"F7" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_F7]]]];
	[functionKeys addSubview:[self buttonWithFrame:CGRectMake(280,   0, 40, 40) title:@"F8" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_F8]]]];
	[functionKeys addSubview:[self buttonWithFrame:CGRectMake(160,  40, 40, 40) title:@"F9" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_F9]]]];
	[functionKeys addSubview:[self buttonWithFrame:CGRectMake(200,  40, 40, 40) title:@"F10" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_F10]]]];
	[functionKeys addSubview:[self buttonWithFrame:CGRectMake(240,  40, 40, 40) title:@"F11" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_F11]]]];
	[functionKeys addSubview:[self buttonWithFrame:CGRectMake(280,  40, 40, 40) title:@"F12" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_F12]]]];
	
	[functionKeys addSubview:[self buttonWithFrame:CGRectMake(240, 120, 40, 40) title:@"<<" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_Back]]]];
	[functionKeys addSubview:[self buttonWithFrame:CGRectMake(280, 120, 40, 40) title:@">>" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_Forward]]]];
	
/*
	[functionKeys addSubview:[self buttonWithFrame:CGRectMake(120,  80, 40, 40) title:@"Vol+" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_]]]];
	[functionKeys addSubview:[self buttonWithFrame:CGRectMake(120, 120, 40, 40) title:@"Vol-" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_]]]];
	[functionKeys addSubview:[self buttonWithFrame:CGRectMake( 80,  80, 40, 40) title:@"Vol0" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_]]]];
	[functionKeys addSubview:[self buttonWithFrame:CGRectMake( 40,  80, 40, 40) title:@"■" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_]]]];
	[functionKeys addSubview:[self buttonWithFrame:CGRectMake(  0, 120, 40, 40) title:@"|<" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_]]]];
	[functionKeys addSubview:[self buttonWithFrame:CGRectMake( 40, 120, 40, 40) title:@">||" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_]]]];
	[functionKeys addSubview:[self buttonWithFrame:CGRectMake( 80, 120, 40, 40) title:@">|" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_]]]];
*/
	
	/*
	[functionKeys addSubview:[self buttonWithFrame:CGRectMake(  0,   0, 40, 40) title:@"" keyArray:[NSArray arrayWithObject:[NSNumber numberWithInt:Key_]]]];
	*/
	
	[keysView transition:0 toView:currentKeysView = normalKeys];
	
	// キーボードで隠れる部分をPadPanelに
	padPanel = [[PadPanel alloc] initWithFrame:CGRectMake(0, keysFrame.origin.y + 160, frame.size.width, [UIKeyboard defaultSize].height - 49)];
	[self addSubview:padPanel];
	
	// delegate
	delegate = nil;
	
	return self;
}

- (BOOL)canBecomeFirstResponder
{
	return YES;
}

- (void)setDelegate:(id)deleg
{
	delegate = deleg;
	[textView setDelegate:self];
	[padPanel setDelegate:deleg];
}

- (void)buttonPressed:(UIButton *)button
{
	if ([[NSUserDefaults standardUserDefaults] boolForKey: @"enable_click_sound"])
		AudioServicesPlaySystemSound(1105);
	
	NSArray *keyCodes = (NSArray *)[keySets objectForKey:[NSNumber numberWithInt:button]];
	if (keyCodes == nil)
	{
		NSString *title = [button currentTitle];
		if (title == nil)	return;
		if ([title isEqualToString:@"Hide"])
		{
			[self.textView resignFirstResponder];
		}
		else if ([title isEqualToString:@"Fn"])
		{
			[keysView transition:0 toView:currentKeysView = (currentKeysView == normalKeys ? functionKeys : normalKeys)];
		}
		else if ([title isEqualToString:@"Shift"])
		{
			if (shiftLock)
			{
				shiftLock = NO;
				[self releaseModifierKeys];
			}
			else if (shiftDown)
			{
				[button setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal];
				shiftLock = YES;
			}
			else
			{
				[delegate qtKeyPressed:Key_Shift];
				[button setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
				shiftDown = YES;
			}
		}
		else if ([title isEqualToString:@"Ctrl"])
		{
			if (ctrlLock)
			{
				ctrlLock = NO;
				[self releaseModifierKeys];
			}
			else if (ctrlDown)
			{
				[button setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal];
				ctrlLock = YES;
			}
			else
			{
				[delegate qtKeyPressed:Key_Control];
				[button setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
				ctrlDown = YES;
			}
		}
		else if ([title isEqualToString:@"Alt"])
		{
			if (altLock)
			{
				altLock = NO;
				[self releaseModifierKeys];
			}
			else if (altDown)
			{
				[button setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal];
				altLock = YES;
			}
			else
			{
				[delegate qtKeyPressed:Key_Alt];
				[button setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
				altDown = YES;;
			}
		}
		else if ([title isEqualToString:@"Win"])
		{
			if (winLock)
			{
				winLock = NO;
				[self releaseModifierKeys];
			}
			else if (winDown)
			{
				[button setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal];
				winLock = YES;
			}
			else
			{
				[delegate qtKeyPressed:Key_Meta];
				[button setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
				winDown = YES;
			}
		}
		return;
	}
	
	for (int keys = 0; keys != [keyCodes count]; ++keys)
	{
		int keyCode = [[keyCodes objectAtIndex:keys] intValue];
		[self qtKeyPressed:keyCode];
	}
}

- (void)buttonReleased:(UIButton *)button
{
	NSArray *keyCodes = (NSArray *)[keySets objectForKey:[NSNumber numberWithInt:button]];
	
	for (int keys = ([keyCodes count] - 1); 0 <= keys; --keys)
	{
		int keyCode = [[keyCodes objectAtIndex:keys] intValue];
		[self qtKeyReleased:keyCode];
	}
}

- (void)releaseModifierKeys
{
	if (shiftDown && !shiftLock)
	{
		[delegate qtKeyReleased:Key_Shift];
		[shift setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
		shiftDown = NO;
	}
	if (ctrlDown && !ctrlLock)
	{
		[delegate qtKeyReleased:Key_Control];
		[ctrl setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
		ctrlDown = NO;
	}
	if (altDown && !altLock)
	{
		[delegate qtKeyReleased:Key_Alt];
		[alt setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
		altDown = NO;
	}
	if (winDown && !winLock)
	{
		[delegate qtKeyReleased:Key_Meta];
		[win setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
		winDown = NO;
	}
}

- (BOOL)isModifierKey:(int)key
{
	if (key == Key_Shift || key == Key_Control || key == Key_Alt || key == Key_Meta)
		return YES;
	return NO;
}

- (void)qtKeyClicked:(int)key
{
	[delegate qtKeyClicked:key];
	if (![self isModifierKey:key])	[self releaseModifierKeys];
}

- (void)qtKeyPressed:(int)key
{
	[delegate qtKeyPressed:key];
	if (![self isModifierKey:key])	[self releaseModifierKeys];
}

- (void)qtKeyReleased:(int)key
{
	[delegate qtKeyReleased:key];
	if (![self isModifierKey:key])	[self releaseModifierKeys];
}

- (void)sendingTextRequested:(NSString *)text
{
	[delegate sendingTextRequested:text];
}

@end
